package com.cms.lib_complier

import com.cms.lib_annoation.GenerateFile
import com.google.auto.service.AutoService
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.TypeSpec
import java.io.File
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.Filer
import javax.annotation.processing.Messager
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.Processor
import javax.annotation.processing.RoundEnvironment
import javax.annotation.processing.SupportedAnnotationTypes
import javax.annotation.processing.SupportedSourceVersion
import javax.lang.model.SourceVersion
import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind
import javax.lang.model.element.TypeElement
import javax.lang.model.util.Elements
import javax.lang.model.util.Types
import javax.tools.Diagnostic

@AutoService(Processor::class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("com.cms.lib_annoation.GenerateFile")
class FileProcessor : AbstractProcessor() {
    //操作元素的工具
    private var elementTool: Elements? = null

    //打印日志
    private var messager: Messager? = null
    private var typeTool: Types? = null
    private var filer: Filer? = null
    private var moduleName: String? = null

    companion object {
        const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"

    }
    @Synchronized
    override fun init(processingEnv: ProcessingEnvironment) {
        super.init(processingEnv)
        elementTool = processingEnv.elementUtils
        messager = processingEnv.messager
        typeTool = processingEnv.typeUtils
        filer = processingEnv.filer
        //获取module名称
        moduleName = processingEnv.options["MODULE_NAME"]
        println("----初始化----")
        messager?.printMessage(Diagnostic.Kind.NOTE,"生成类---1111-")
    }

    override fun process(set: Set<TypeElement?>, roundEnvironment: RoundEnvironment): Boolean {
        messager?.printMessage(Diagnostic.Kind.NOTE,"生成类---1111-")
        //查询被GenerateFile 注释的元素
        val elements = roundEnvironment.getElementsAnnotatedWith(
            GenerateFile::class.java
        )

        if (elements.isEmpty()) return false
        val iterator: Iterator<Element> = elements.iterator()
        while (iterator.hasNext()) {
            val element = iterator.next()
            if (element.kind == ElementKind.CLASS) {
                processAnnotation(element)
            } else {
                messager!!.printMessage(Diagnostic.Kind.ERROR, "GenerateFile注解必须作用在类上")
                break
            }
        }
        return false
    }

    private fun processAnnotation(element: Element) {

       messager?.printMessage(Diagnostic.Kind.NOTE,"生成类----")

        //获取类名
        val className = element.simpleName.toString()
        //获取包名
        val packetName = processingEnv.elementUtils.getPackageOf(element).toString()
        //定义文件名称
        val fileName = "$moduleName$className"

        //生成文件
        val fileBuilder = FileSpec.builder(packetName, fileName.uppercase())

        //生成类
        val classBuilder = TypeSpec.classBuilder(fileName).addModifiers(KModifier.PUBLIC)

       //addProperty(classBuilder, element)


        val outDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME]
        //构建并指定输出位置
        fileBuilder.addType(classBuilder.build()).build()
            .writeTo(File(outDir))
    }

   /* fun  addProperty(classBuilder: TypeSpec.Builder,classElement:Element){
        classBuilder.addProperty(PropertySpec.builder("age",classElement.asType().asTypeName().copy(nullable = true)  //可空属性
            ,KModifier.PRIVATE)//私有属性
            .mutable()//参数var
            .initializer("null").build())
    }
    */
}
